home *** CD-ROM | disk | FTP | other *** search
- /* Style Toy: Allows user manipulation of styles StyleToy.m
- ** --------- ----------------------------------
- */
-
- #import "StyleToy.h"
- #import "HTParse.h"
- #import "HTStyle.h"
- #import "HTUtils.h"
-
- #import "HyperText.h"
- #define THIS_TEXT (HyperText *)[[[NXApp mainWindow] contentView] docView]
-
- /* Field numbers in the parameter form:
- */
- #define SGMLTAG_FIELD 4
- #define FONT_NAME_FIELD 2
- #define FONT_SIZE_FIELD 3
- #define FIRST_INDENT_FIELD 0
- #define SECOND_INDENT_FIELD 1
-
- @implementation StyleToy
-
- extern char * appDirectory; /* Pointer to directory for application */
-
- // Global styleSheet available to every one:
-
- HTStyleSheet * styleSheet = 0;
-
- static HTStyle * style; /* Current Style */
- static OpenPanel * open_panel; /* Keep the open panel alive */
- static SavePanel * save_panel; /* Keep a Save panel too */
-
- // Create new one:
-
- + new
- {
- self = [super new];
- [self loadDefaultStyleSheet];
- return self;
- }
-
- // Set connections to other objects:
-
- - setTabForm:anObject
- {
- TabForm = anObject;
- return self;
- }
-
- - setParameterForm:anObject
- {
- ParameterForm = anObject;
- return self;
- }
-
- - setStylePanel:anObject
- {
- StylePanel = anObject;
- return self;
- }
-
- - setNameForm:anObject
- {
- NameForm = anObject;
- return self;
- }
-
-
- // ACTION METHODS
- // ==============
-
- // Display style in the panel
-
- - display_style
- {
- if(style->name) [NameForm setStringValue:style->name at:0];
- else [NameForm setStringValue:"" at:0];
-
- if(style->SGMLTag) [ParameterForm setStringValue:style->SGMLTag at:SGMLTAG_FIELD];
- else [ParameterForm setStringValue:"" at:SGMLTAG_FIELD];
-
- [ParameterForm setStringValue:[style->font name] at:FONT_NAME_FIELD];
-
- [ParameterForm setFloatValue:style->fontSize at:FONT_SIZE_FIELD];
-
- if(style->paragraph) {
- char tabstring[255];
- int i;
- [ParameterForm setFloatValue:style->paragraph->indent1st
- at:FIRST_INDENT_FIELD];
- [ParameterForm setFloatValue:style->paragraph->indent2nd
- at:SECOND_INDENT_FIELD];
- tabstring[0]=0;
- for(i=0; i < style->paragraph->numTabs; i++) {
- sprintf(tabstring+strlen(tabstring), "%.0f ", style->paragraph->tabs[i].x);
- }
- [TabForm setStringValue:tabstring at:0];
- }
- return self;
- }
-
-
- // Load style from Panel
- //
- // @@ Tabs not loaded
-
- -load_style
- {
- char * name = 0;
- char * stripped;
-
- style->fontSize=[ParameterForm floatValueAt:FONT_SIZE_FIELD];
- StrAllocCopy(name, [NameForm stringValueAt:0]);
- stripped = HTStrip(name);
- if (*stripped) {
- id font;
- font = [Font newFont:stripped size:style->fontSize];
- if (font) style->font = font;
- }
- free(name);
- name = 0;
-
- StrAllocCopy(name, [ParameterForm stringValueAt:SGMLTAG_FIELD]);
- stripped = HTStrip(name);
- if (*stripped) {
- StrAllocCopy(style->SGMLTag, stripped);
- }
- free(name);
- name = 0;
-
- if (!style->paragraph) style->paragraph = malloc(sizeof(*(style->paragraph)));
- style->paragraph->indent1st = [ParameterForm floatValueAt: FIRST_INDENT_FIELD];
- style->paragraph->indent2nd = [ParameterForm floatValueAt: SECOND_INDENT_FIELD];
-
- return self;
- }
-
-
- // Open a style sheet from a file
- // ------------------------------
- //
- // We overlay any previously defined styles with new ones, but leave
- // old ones which are not redefined.
-
- - open:sender
- {
- NXStream * s; // The file stream
- const char * filename; // The name of the file
- char *typelist[2] = {"style",(char *)0}; // Extension must be ".style."
-
- if (!open_panel) {
- open_panel = [OpenPanel new];
- [open_panel allowMultipleFiles:NO];
- }
-
- if (![open_panel runModalForTypes:typelist]) {
- if (TRACE) printf("No file selected.\n");
- return nil;
- }
-
- filename = [open_panel filename];
- s = NXMapFile(filename, NX_READONLY);
- if (!s) {
- if(TRACE) printf("Styles: Can't open file %s\n", filename);
- return nil;
- }
- if (!styleSheet) styleSheet = HTStyleSheetNew();
- StrAllocCopy(styleSheet->name, filename);
- if (TRACE) printf("Stylesheet: New one called %s.\n", styleSheet->name);
- (void)HTStyleSheetRead(styleSheet, s);
- NXCloseMemory(s, NX_FREEBUFFER);
- style = styleSheet->styles;
- [self display_style];
- return self;
- }
-
-
- // Load default style sheet
- // ------------------------
- //
- // We load EITHER the user's style sheet (if it exists) OR the system one.
- // This saves a bit of time on load. An alternative would be to load the
- // system style sheet and then overload the styles in the user's, so that
- // he could redefine a subset only of the styles.
- // If the HOME directory is defined, then it is always used a the
- // style sheet name, so that any changes will be saved in the user's
- // $(HOME)/WWW directory.
-
- - loadDefaultStyleSheet
- {
- NXStream * stream;
-
- if (!styleSheet) styleSheet = HTStyleSheetNew();
- styleSheet->name = malloc(strlen(appDirectory)+13+1);
- strcpy(styleSheet->name, appDirectory);
- strcat(styleSheet->name, "default.style");
-
- if (getenv("HOME")) {
- char name[256];
- strcpy(name, getenv("HOME"));
- strcat(name, "/WWW/default.style");
- StrAllocCopy(styleSheet->name, name);
- stream = NXMapFile(name, NX_READONLY);
- } else stream = 0;
-
- if (!stream) {
- char name[256];
- strcpy(name, appDirectory);
- strcat(name, "default.style");
- if (TRACE) printf("Couldn't open $(HOME)/WWW/default.style\n");
- stream = NXMapFile(name, NX_READONLY);
- if (!stream)
- printf("Couldn't open %s, errno=%i\n", name, errno);
- }
-
- if (stream) {
- (void)HTStyleSheetRead(styleSheet, stream);
- NXCloseMemory(stream, NX_FREEBUFFER);
- style = styleSheet->styles;
- [self display_style];
- }
- return self;
- }
-
-
- // Save style sheet to a file
- // --------------------------
-
- - saveAs:sender
- {
- NXStream * s; // The file stream
- char * slash;
- int status;
- char * suggestion=0; // The name of the file to suggest
- const char * filename; // The name chosen
-
- if (!save_panel) {
- save_panel = [SavePanel new]; // Keep between invocations
- }
-
- StrAllocCopy(suggestion,styleSheet->name);
- slash = rindex(suggestion, '/'); // Point to last slash
- if (slash) {
- *slash++ = 0; /* Separate directory and filename */
- status = [save_panel runModalForDirectory:suggestion file:slash];
- } else {
- status = [save_panel runModalForDirectory:"." file:suggestion];
- }
- free(suggestion);
-
- if (!status) {
- if (TRACE) printf("No file selected.\n");
- return nil;
- }
-
- filename = [save_panel filename];
- s = NXMapFile(filename, NX_WRITEONLY);
- if (!s) {
- if(TRACE) printf("Styles: Can't open file %s for write\n", filename);
- return nil;
- }
- StrAllocCopy(styleSheet->name, filename);
- if (TRACE) printf("StylestyleSheet: Saving as `%s'.\n", styleSheet->name);
- (void)HTStyleSheetWrite(styleSheet, s);
- NXSaveToFile(s, styleSheet->name);
- NXCloseMemory(s, NX_FREEBUFFER);
- style = styleSheet->styles;
- [self display_style];
- return self;
- }
-
-
- // Move to next style
- // ------------------
-
- - NextButton:sender
- {
- if (styleSheet->styles)
- if (styleSheet->styles->next)
- if (style->next) {
- style = style->next;
- } else {
- style = styleSheet->styles;
- }
- [self display_style];
- return self;
- }
-
-
- - FindUnstyledButton:sender
- {
- [THIS_TEXT selectUnstyled: styleSheet];
- return self;
- }
-
- // Apply current style to selection
- // --------------------------------
-
- - ApplyButton:sender
- {
- [THIS_TEXT applyStyle:style];
- return self;
- }
-
- - applyStyleNamed: (const char *)name
- {
- HTStyle * thisStyle = HTStyleNamed(styleSheet, name);
- if (!thisStyle) return nil;
- return [THIS_TEXT applyStyle:thisStyle];
- }
-
- - heading1Button:sender { return [self applyStyleNamed:"Heading1" ]; }
- - heading2Button:sender { return [self applyStyleNamed:"Heading2" ]; }
- - heading3Button:sender { return [self applyStyleNamed:"Heading3" ]; }
- - heading4Button:sender { return [self applyStyleNamed:"Heading4" ]; }
- - heading5Button:sender { return [self applyStyleNamed:"Heading5" ]; }
- - heading6Button:sender { return [self applyStyleNamed:"Heading6" ]; }
- - normalButton:sender { return [self applyStyleNamed:"Normal" ]; }
- - addressButton:sender { return [self applyStyleNamed:"Address" ]; }
- - exampleButton:sender { return [self applyStyleNamed:"Example" ]; }
- - listButton:sender { return [self applyStyleNamed:"List" ]; }
- - menuButton:sender { return [self applyStyleNamed:"Menu" ]; }
- - dirButton:sender { return [self applyStyleNamed:"Dir" ]; }
- - glossaryButton:sender { return [self applyStyleNamed:"Glossary" ]; }
-
-
- // Move to previous style
- // ----------------------
-
- - PreviousButton:sender
- {
- HTStyle * scan;
- for (scan = styleSheet->styles; scan; scan=scan->next) {
- if ((scan->next==style) || (scan->next==0)){
- style = scan;
- break;
- }
- }
- [self display_style];
- return self;
- }
-
- - SetButton:sender
- {
- [self load_style];
- [THIS_TEXT updateStyle:style];
- return self;
- }
-
- - PickButton:sender
- {
- HTStyle * st = [THIS_TEXT selectionStyle:styleSheet];
- if (st) {
- style = st;
- [self display_style];
- }
- return self;
- }
-
- - ApplyToSimilar:sender
- {
- return [THIS_TEXT applyToSimilar:style];
- }
-
-
- @end
-